using System;

namespace ECCIT.Data
{
	/// <summary>
	/// </summary>
	[Serializable]
	public class Column : IColumn
	{
		public static readonly int DefaultLength = -1;
		public static readonly int DefaultScale = -1;

		private DataType _type;
		private int _length;
		private int _scale;
		private string _name;
		private bool _nullable;

		/// <summary>
		///		Get or set the column name
		/// </summary>
		public string Name
		{
			get{ return _name; }
			set{ _name = value; }
		}

		/// <summary>
		///		Get or set the column type
		/// </summary>
		public DataType Type
		{
			get{ return _type; }
			set{ _type = value; }
		}

		/// <summary>
		///		Get or set the column length or precision
		/// </summary>
		public int Length
		{
			get{ return _length; }
			set{ _length = value; }
		}

		/// <summary>
		///		Get or set the column scale
		/// </summary>
		public int Scale
		{
			get{ return _scale; }
			set{ _scale = value; }
		}
		
		/// <summary>
		/// 	Get or set if this column could be NULL
		/// </summary>
		public bool Nullable
		{
			get { return this._nullable; }
			set { this._nullable = value; }
		}

        public int? MaxLength
        {
            get {
                int? maxLength = null;
                switch (this.Type)
                {
                    case DataType.String:
                    case DataType.Date:
                    case DataType.DateTime:
                    case DataType.Time:
                    case DataType.YearMonth:
                        maxLength = this.Length; 
                        break;
                    case DataType.BigInt:
                        maxLength = long.MaxValue.ToString().Length;
                        break;
                    case DataType.Int:
                        maxLength = int.MaxValue.ToString().Length;
                        break;
                    case DataType.Binary:
                        break;
                    case DataType.Decimal:
                        maxLength = this.Length + 1;    // "." holds one place
                        break;
                    case DataType.NText:
                        break;
                }

                return maxLength;
            }
        }

		/// <summary>
		///		The default constructor is only designed for AjaxPro
		/// </summary>
		public Column(){}
		
		private static Column CreateInstance(DataType type, string name, int precision, int scale, bool nullable)
		{
			Column column = new Column();
			column.Type = type;
			column.Name = name;
			column.Length = precision;
			column.Scale = scale;
			column.Nullable = nullable;
			
			return column;
		}

		/// <summary>
		///		The Column constructor which fits for some DataType enum value
		/// </summary>
		/// <param name="type">
		///		DataType.Int
		///		DataType.NText
		///		DataType.Binary
		///		DataType.Date
		///		DataType.DateTime
		///		DataType.YearMonth
		///		DataType.Time
		/// </param>
		/// <param name="name">column name</param>
		public Column(DataType type, string name) : this(type, name, true)
		{
			
		}
		
		public Column(DataType type, string name, bool nullable) : this(type, name, DefaultLength, nullable)
		{
		}

		/// <summary>
		///		The Column constructor is only fit for DataType.String
		/// </summary>
		/// <param name="type">
		///		DataType.String
		/// </param>
		/// <param name="name"></param>
		/// <param name="length"></param>
		public Column(DataType type, string name, int length) : this(type, name, length, true)
		{
			
		}
		
		public Column(DataType type, string name, int length, bool nullable) : this(type, name, length, DefaultScale, nullable)
		{
		}

		/// <summary>
		///		The Column constructor is only fit for DataType.Decimal
		/// </summary>
		/// <param name="type">DataType.Decimal</param>
		/// <param name="name">Column name</param>
		/// <param name="precision">Column precision</param>
		/// <param name="scale">Column scale</param>
		public Column(DataType type, string name, int precision, int scale) : this(type, name, precision, scale, true)
		{
			
		}
		
		public Column(DataType type, string name, int precision, int scale, bool nullable)
		{
			this._type = type;
			this._name = name;
			this._length = precision;
			this._scale = scale;
			this._nullable = nullable;
		}
	}
}
